home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
os20
/
util
/
newpop40_aga.lha
/
NewPop-4.0AGA
/
NewPop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-07
|
38KB
|
1,420 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1986 The Software Distillery. All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of */
/* | . | || the authors. */
/* | o | || Dave Baker Ed Burnette Stan Chow Jay Denebeim */
/* | . |// Gordon Keener Jack Rouse John Toebes Doug Walker */
/* ====== BBS:(919)-471-6436 VOICE:(919)-469-4210 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* VERY loosely based on the input.device example by Rob Peck, 12/1/85
*
*
* Additions and modifications Copyright (c) 1989, 1990, 1991 Loren J. Rittle
* Modifications Copyright (c) 1990 Ed A. Hutchins and Loren J. Rittle
*
* As stated in the original POPCLI documentation file:
*
* Permission is hereby granted to distribute this program provided
* both the documentation accompanies the executable and that no
* charge is made for its distribution.
* I assume that this statement includes the right to modify the source
* and futher distribute the modified work under this same agreement. - LJR
* (Actually, at this point, 'diff newpop.c popcli3.c | wc'
* > 'wc -c newpop.c' + 'wc -c popcli3.c'. :-)
*
*
* Note: Some code to do the Q*X pattern lifted (and modified) from:
* Line drawing demo for the Commodore/Amiga
* Written by John Riley, Lattice, Inc.
*
* Note: The spawning of a lower priority task to do graphics
* was inspired by Mackie to some degree (and by
* one person who claimed that NewPop slowed down
* HST modem transfers! I think that they were
* on a non-A3000 class machine :-) Later, I got
* a report that it also happened on an A3000! :-(
* See NICENEWPOP in `[s:].newpoprc'.
*
* UpfrontLayer is used instead of WindowToFront() because of
* a WorkBench/INTUITION bug. From dmouse.doc:
*
* WORKBENCH USERS!!!!!!!!!! There appears to be a bug in
* intuition's WindowToFront() call, which can lock up
* intuition when workbench icons are active. Under the
* defaults, this will occur whenever you depress the left
* mouse button over an icon.
*
* Thanks to Matt Dillon for showing the work around
* in DMouse's source code.
*
* See ChangeLog for the record of changes.
*
* Loren J. Rittle
* l-rittle@uiuc.edu
*/
/* * * * * * * * * * * INCLUDES * * * * * * * * * * * * */
#pragma msg 148 ignore push
#pragma msg 149 ignore push
#pragma msg 61 ignore push
#include <exec/exec.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <devices/timer.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/layers.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
/*int GetString (char *, char *, struct Window *, int, int);
#include <proto/req.h>*/
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/layers.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/diskfont.h>
#pragma msg 149 pop
#pragma msg 61 pop
#include <string.h>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
LoadRGB32 (void *, unsigned long *table);
#pragma libcall GfxBase LoadRGB32 372 9802
/* * * * * * * * * * * CONSTANTS * * * * * * * * * * * * */
#define PORTNAME "NewPop.port"
/* The name of our well known *PRIVATE* message port */
#define MAXCMD 200
#define MAXTASKNAME 32
#define MAXFONTNAME 32
#define MAXPASSWORD 32
/* Maximum string size of various things */
#define BANNER \
"\x9B" "0;33mNewPop\x9B" \
"0m v4.0 by Loren J. Rittle - Copyright \xA9 1989 - 1991 Based upon:\n" \
"\x9B" "0;33mPOPCLI III\x9B" \
"0m by John Toebes - Copyright \xA9 1987 The Software Distillery\n"
/* The hello banner */
#define ALREADYHEREMESSAGE \
"NewPop is already running, you should use `break [cli number of NewPop]'\n" \
"to kill it before starting another. Or, if started via the WorkBench,\n" \
"another double click on the NewPop icon will stop it.\n"
/* The already here message :-) */
/* * * * * * * * * * * * * * * * TYPES * * * * * * * * * * * * * */
struct color
{
int red, green, blue;
};
enum OptionTypes
{
boolean, integer, string
};
struct NewPopOption
{
char *name;
enum OptionTypes type;
union
{
int ivalue;
char *svalue;
} value;
int min, max;
};
/* * * * * * * * * * * EXTERNALS AND GLOBAL DATA * * * * * * * * */
char FontName[MAXFONTNAME] = "Helvetica.font";
char TaskName[MAXTASKNAME] = "gvpscsi.device";
#ifndef LJR_FAVORITE
char Cmd[MAXCMD] = "NEWCLI >NIL:";
#else
char Cmd[MAXCMD] = "NewWSH <nil: >nil: cnn:0/11/640/189/WShell/c";
#endif
char PassWord[MAXPASSWORD] = "Amiga";
/*
* See .newpoprc for the meanings of these options!
*/
struct NewPopOption NewPopOptions[] =
{
#define NICENEWPOP (NewPopOptions[0].value.ivalue)
{"NICENEWPOP", boolean, 1, 0, 1},
#define NEWPOPLITE (NewPopOptions[1].value.ivalue)
{"NEWPOPLITE", boolean, 0, 0, 1},
#define WEWANTWINDOWDRAG (NewPopOptions[2].value.ivalue)
{"WEWANTWINDOWDRAG", boolean, 0, 0, 1},
#define SCSITASKNAME (NewPopOptions[3].value.svalue)
{"SCSITASKNAME", string, (int) TaskName, 0, MAXTASKNAME},
#define FONTNAME (NewPopOptions[4].value.svalue)
{"FONTNAME", string, (int) FontName, 0, MAXFONTNAME},
#define COMMAND (NewPopOptions[5].value.svalue)
{"COMMAND", string, (int) Cmd, 0, MAXCMD},
#define MAXSCSIUSAGE (NewPopOptions[6].value.ivalue)
{"MAXSCSIUSAGE", integer, 55, 20, 255},
#define SCSIIOMONWIDTH (NewPopOptions[7].value.ivalue)
{"SCSIIOMONWIDTH", integer, 100, 0, 1024},
#define CPULOADMONWIDTH (NewPopOptions[8].value.ivalue)
{"CPULOADMONWIDTH", integer, 100, 0, 1024},
#define GAPBETWEEN2 (NewPopOptions[9].value.ivalue)
{"GAPBETWEEN2", integer, 16, 0, 256},
#define GAPBETWEEN (NewPopOptions[10].value.ivalue)
{"GAPBETWEEN", integer, 16, 0, 256},
#define FONTSIZE (NewPopOptions[11].value.ivalue)
{"FONTSIZE", integer, 9, 4, 56},
#define STARTYOFFSET (NewPopOptions[12].value.ivalue)
{"STARTYOFFSET", integer, 7, 2, 60},
#define MAXTEXTWIDTH (NewPopOptions[13].value.ivalue)
{"MAXTEXTWIDTH", integer, 107, 10, 1024},
#define STARTXOFFSET (NewPopOptions[14].value.ivalue)
{"STARTXOFFSET", integer, 56, 10, 200},
#define WINDOWHEIGHT (NewPopOptions[15].value.ivalue)
{"WINDOWHEIGHT", integer, 8, 4, 56},
#define TIMEOUT (NewPopOptions[16].value.ivalue)
{"TIMEOUT", integer, 180, 0, 0x00ffffff},
#define POPKEY (NewPopOptions[17].value.ivalue)
{"POPKEY", integer, 69, 0, 255},
#define BLANKERPRIORITY (NewPopOptions[18].value.ivalue)
{"BLANKERPRIORITY", integer, -20, -20, 10},
#define ULC (NewPopOptions[19].value.ivalue)
{"ULC", integer, 0, 0, 2},
#define URC (NewPopOptions[20].value.ivalue)
{"URC", integer, 1, 0, 2},
#define LLC (NewPopOptions[21].value.ivalue)
{"LLC", integer, 0, 0, 2},
#define LRC (NewPopOptions[22].value.ivalue)
{"LRC", integer, 2, 0, 2},
#define INSTANTKEY (NewPopOptions[23].value.ivalue)
{"INSTANTKEY", integer, 0, 0, 255},
#define DEFEATKEY (NewPopOptions[24].value.ivalue)
{"DEFEATKEY", integer, 0, 0, 255},
#define LOCK (NewPopOptions[25].value.ivalue)
{"LOCK", boolean, 0, 0, 1},
#define PASSWORD (NewPopOptions[26].value.svalue)
{"PASSWORD", string, (int) PassWord, 0, MAXPASSWORD},
#define MEMORYMONWIDTH (NewPopOptions[27].value.ivalue)
{"MEMORYMONWIDTH", integer, 0, 0, 1024},
#define GAPBETWEEN3 (NewPopOptions[28].value.ivalue)
{"GAPBETWEEN3", integer, 0, 0, 256},
#define BACKDROPWINDOW (NewPopOptions[29].value.ivalue)
{"BACKDROPWINDOW", boolean, 1, 0, 1},
#define WIMPYCLOCK (NewPopOptions[30].value.ivalue)
{"WIMPYCLOCK", boolean, 0, 0, 1},
/* Add new enties before this line! */
{NULL, boolean, 0, 0, 0}
};
struct IntuitionBase *IntuitionBase;
struct LayersBase *LayersBase;
struct GfxBase *GfxBase;
struct Library *DiskfontBase;
struct DosLibrary *DosBase;
struct ExecBase *ExecBase;
struct Library *ReqBase;
struct NewScreen NewScreen =
{0, 0, 640, 400, 1, 0, 1, HIRES | LACE, SCREENBEHIND | SCREENQUIET | CUSTOMSCREEN, NULL, NULL, NULL, NULL};
struct NewWindow NewBlankerWindow =
{0, 0, 640, 400, 0xff, 0xff, 0, RMBTRAP | BORDERLESS | BACKDROP | SIMPLE_REFRESH | ACTIVATE, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN};
int WindowWidth, WindowHeight;
struct Gadget WDragGadget =
{NULL, 0, 0, 0, 0, GADGHNONE, NULL, WDRAGGING, NULL, NULL, NULL, NULL, NULL, 0, 0};
struct NewWindow NewWindow =
{0, 0, 0, 0, 2, 1, 0, BORDERLESS | NOCAREREFRESH, &WDragGadget, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN};
struct Task *buddy;
ULONG creatclisig;
ULONG unblanksig;
ULONG mousemovesig;
ULONG noevents;
short creatsignum = -1;
short blanksignum = -1;
short mousemovenum = -1;
struct Screen *blankscreen;
struct Window *blankwindow;
USHORT instantblank, defeatblank;
ULONG scsiDisp;
struct Task *child;
struct Task *securer;
struct ViewPort *blankVP;
struct RastPort *blankRP;
USHORT xlim, ylim;
int maxchip, maxfast;
USHORT StartedFromWB;
/* * * * * * * * * * * PROTOTYPES * * * * * * * * * * * * */
struct InputEvent *__saveds __asm myhandler (register __a0 struct InputEvent *);
void createchild (void);
void __saveds blankertask (void);
void killchild (void);
void createsecurer (void);
void __saveds securertask (void);
void killsecurer (void);
void __saveds scsifriendlosing (void);
int ParseConfigFile (void);
int __stdargs main (int argc, char *argv[]);
void changecolor (void);
void updatedisplay (void);
void QueueTimer (struct timerequest *, ULONG);
/* * * * * * * * * * * OUR ROUTINES * * * * * * * * * * * */
struct InputEvent *__saveds __asm
myhandler (register __a0 struct InputEvent * ev)
{
struct InputEvent *ep, *laste;
for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
{
if ((ep->ie_Class == IECLASS_RAWKEY) &&
(ep->ie_Qualifier & IEQUALIFIER_LCOMMAND))
{
if ((ep->ie_Code == POPKEY) && (POPKEY))
Signal (buddy, creatclisig);
else if ((ep->ie_Code == DEFEATKEY) && (DEFEATKEY))
{
defeatblank = !defeatblank;
instantblank = 0;
}
else if ((ep->ie_Code == INSTANTKEY) && (INSTANTKEY))
{
defeatblank = 0;
instantblank = !instantblank;
}
else
goto nomatch;
if (laste == NULL)
ev = ep->ie_NextEvent;
else
laste->ie_NextEvent = ep->ie_NextEvent;
}
else
nomatch:
laste = ep;
if (ep->ie_Class == IECLASS_RAWMOUSE)
Signal (buddy, mousemovesig);
if (ep->ie_Class != IECLASS_TIMER)
{
noevents = 0;
if (blankscreen)
Signal (buddy, unblanksig);
}
}
return (ev);
}
void
createchild (void)
{
child = CreateTask ("NewPopBlanker", BLANKERPRIORITY, (APTR) blankertask, 4000L);
}
void __saveds
blankertask (void)
{
struct MsgPort *timerport2;
struct timerequest *timerreq2 = NULL;
if (timerport2 = CreatePort ("NewPopTimerPort2", 0))
if (timerreq2 = (struct timerequest *) CreateExtIO (timerport2, sizeof (struct timerequest)))
if (!(OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) timerreq2, 0)))
{
while (!(SetSignal (0L, 0L) & SIGBREAKF_CTRL_C))
{
changecolor ();
updatedisplay ();
if (child->tc_Node.ln_Pri == 10)
SetTaskPri (child, BLANKERPRIORITY);
timerreq2->tr_node.io_Command = TR_ADDREQUEST;
timerreq2->tr_time.tv_secs = 0;
timerreq2->tr_time.tv_micro = 1000000 / 60;
DoIO ((struct IORequest *) timerreq2);
}
}
else
Wait (SIGBREAKF_CTRL_C);
if (timerreq2)
{
if (timerreq2->tr_node.io_Device)
CloseDevice ((struct IORequest *) timerreq2);
DeleteExtIO ((struct IOStdReq *) timerreq2);
}
if (timerport2)
DeletePort (timerport2);
Signal (buddy, SIGBREAKF_CTRL_D);
Wait (0L);
}
void
killchild (void)
{
Signal (child, SIGBREAKF_CTRL_C);
SetTaskPri (child, 20L);
Wait (SIGBREAKF_CTRL_D);
DeleteTask (child);
child = NULL;
}
void
createsecurer (void)
{
securer = CreateTask ("NewPopSecurer", 19, (APTR) securertask, 4000L);
}
void __saveds
securertask (void)
{
while (!(SetSignal (0L, 0L) & SIGBREAKF_CTRL_C))
{
ScreenToFront (blankscreen);
changecolor ();
}
Signal (buddy, SIGBREAKF_CTRL_D);
Wait (0L);
}
void
killsecurer (void)
{
Signal (securer, SIGBREAKF_CTRL_C);
Wait (SIGBREAKF_CTRL_D);
DeleteTask (securer);
securer = NULL;
}
void __saveds
scsifriendlosing (void)
{
scsiDisp++;
}
int
ParseConfigFile (void)
{
BPTR configFile;
#define INPUTBUFFERSIZE 512
char buffer[INPUTBUFFERSIZE];
int bp;
int keyword;
#define KEYWORDBUFFERSIZE 31
char keywordbuffer[KEYWORDBUFFERSIZE + 1];
int keywordbp;
int charinbuffer;
int state = 0;
int line = 1;
int i;
int neg;
configFile = Open (".newpoprc", MODE_OLDFILE);
if (!configFile)
configFile = Open ("s:.newpoprc", MODE_OLDFILE);
if (!configFile)
return 0;
while (charinbuffer = Read (configFile, buffer, INPUTBUFFERSIZE))
{
for (bp = 0; bp != charinbuffer; bp++)
{
switch (state)
{
case 0:
if (buffer[bp] == '#')
state = 1;
else if (buffer[bp] == '\n')
line++;
else if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
{
keywordbuffer[0] = buffer[bp] - 32;
keywordbp = 1;
state = 2;
}
else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
{
keywordbuffer[0] = buffer[bp];
keywordbp = 1;
state = 2;
}
else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
{
state = 1;
goto out;
}
break;
case 1:
if (buffer[bp] == '\n')
{
line++;
state = 0;
}
break;
case 2:
if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
{
if (keywordbp >= KEYWORDBUFFERSIZE)
{
state = 1;
goto out;
}
keywordbuffer[keywordbp++] = buffer[bp] - 32;
}
else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
{
if (keywordbp >= KEYWORDBUFFERSIZE)
{
state = 1;
goto out;
}
keywordbuffer[keywordbp++] = buffer[bp];
}
else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
{
if (keywordbp >= KEYWORDBUFFERSIZE)
{
state = 1;
goto out;
}
keywordbuffer[keywordbp++] = buffer[bp];
}
else if ((buffer[bp] == ' ') || (buffer[bp] == '\t'))
{
keywordbuffer[keywordbp] = '\0';
for (i = 0; NewPopOptions[i].name; i++)
if (!strcmp (NewPopOptions[i].name, keywordbuffer))
break;
if (!NewPopOptions[i].name)
{
state = 1;
goto out;
}
keyword = i;
state = 3;
}
else
{
state = 1;
goto out;
}
break;
case 3:
if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
switch (NewPopOptions[keyword].type)
{
case boolean:
state = 4;
if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
{
keywordbuffer[0] = buffer[bp] - 32;
keywordbp = 1;
}
else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
{
keywordbuffer[0] = buffer[bp];
keywordbp = 1;
}
else
{
state = 1;
goto out;
}
break;
case integer:
state = 5;
neg = 0;
if (buffer[bp] == '-')
{
neg = 1;
NewPopOptions[keyword].value.ivalue = 0;
}
else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
NewPopOptions[keyword].value.ivalue = buffer[bp] - '0';
else
{
state = 1;
goto out;
}
break;
case string:
state = 6;
if (buffer[bp] != '"')
{
state = 1;
goto out;
}
i = 0;
break;
}
break;
case 4:
if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
{
if (keywordbp >= KEYWORDBUFFERSIZE)
{
state = 1;
goto out;
}
keywordbuffer[keywordbp++] = buffer[bp] - 32;
}
else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
{
if (keywordbp >= KEYWORDBUFFERSIZE)
{
state = 1;
goto out;
}
keywordbuffer[keywordbp++] = buffer[bp];
}
else if ((buffer[bp] == ' ') || (buffer[bp] == '\t') || (buffer[bp] == '\n'))
{
keywordbuffer[keywordbp] = '\0';
NewPopOptions[i].value.ivalue = 2;
if (!strcmp ("TRUE", keywordbuffer))
NewPopOptions[i].value.ivalue = 1;
if (!strcmp ("FALSE", keywordbuffer))
NewPopOptions[i].value.ivalue = 0;
if (!strcmp ("ON", keywordbuffer))
NewPopOptions[i].value.ivalue = 1;
if (!strcmp ("OFF", keywordbuffer))
NewPopOptions[i].value.ivalue = 0;
if (NewPopOptions[i].value.ivalue == 2)
{
state = 1;
goto out;
}
if (buffer[bp] == '\n')
{
line++;
state = 0;
}
else
state = 7;
}
else
{
state = 1;
goto out;
}
break;
case 5:
if (buffer[bp] == '\n')
{
if (neg)
NewPopOptions[keyword].value.ivalue *= -1;
if (NewPopOptions[keyword].value.ivalue > NewPopOptions[keyword].max)
{
state = 1;
goto out;
}
if (NewPopOptions[keyword].value.ivalue < NewPopOptions[keyword].min)
{
state = 1;
goto out;
}
line++;
state = 0;
}
else if ((buffer[bp] == ' ') || (buffer[bp] == '\t'))
{
if (neg)
NewPopOptions[keyword].value.ivalue *= -1;
if (NewPopOptions[keyword].value.ivalue > NewPopOptions[keyword].max)
{
state = 1;
goto out;
}
if (NewPopOptions[keyword].value.ivalue < NewPopOptions[keyword].min)
{
state = 1;
goto out;
}
state = 7;
}
else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
{
NewPopOptions[keyword].value.ivalue *= 10;
NewPopOptions[keyword].value.ivalue += buffer[bp] - '0';
}
else
{
state = 1;
goto out;
}
break;
case 6:
if ((buffer[bp] == '\n') || (i >= NewPopOptions[keyword].max))
{
state = 1;
goto out;
}
NewPopOptions[keyword].value.svalue[i++] = buffer[bp];
if (buffer[bp] == '"')
{
NewPopOptions[keyword].value.svalue[--i] = '\0';
state = 8;
}
break;
case 7:
if (buffer[bp] == '#')
state = 1;
else if (buffer[bp] == '\n')
{
line++;
state = 0;
}
else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
{
state = 1;
goto out;
}
break;
case 8:
if (buffer[bp] == '\n')
{
line++;
state = 0;
}
else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
{
state = 1;
goto out;
}
else
state = 7;
break;
default:
state = 1;
goto out;
}
}
}
out:
Close (configFile);
if (state)
{
if (!StartedFromWB)
{
sprintf (buffer, "NewPop: parse error on line %d of .newpoprc\n", line);
Write (Output (), buffer, strlen (buffer));
}
return 1;
}
return 0;
}
int __stdargs
main (int argc, char *argv[])
{
USHORT scsifriendinstalled = 0;
ULONG timersig, LIdle, LDisp;
BPTR nullfh = NULL;
struct MsgPort *port;
struct MsgPort *timerport = NULL;
struct MsgPort *inputDevPort = NULL;
struct timerequest *timerreq = NULL;
struct IOStdReq *inputRequestBlock = NULL;
struct TextFont *textFont = NULL;
struct Task *scsifriend;
struct Interrupt handlerStuff;
struct Window *titlewindow = NULL;
struct RastPort *titleRP;
UBYTE oldPriority;
{
buddy = FindTask (NULL);
oldPriority = SetTaskPri (buddy, 20);
if (!argc)
StartedFromWB = 1;
Forbid ();
if (!(port = FindPort (PORTNAME)))
{
if (!(port = CreatePort (PORTNAME, 0)))
{
Permit ();
goto grandexit;
}
Permit ();
if (!StartedFromWB)
Write (Output (), BANNER, sizeof (BANNER));
if (ParseConfigFile ())
goto abort;
}
else
{
Permit ();
if (StartedFromWB)
Signal (port->mp_SigTask, SIGBREAKF_CTRL_C);
else
Write (Output (), ALREADYHEREMESSAGE, sizeof (ALREADYHEREMESSAGE));
goto grandexit;
}
if (!(nullfh = Open ("NIL:", MODE_NEWFILE)))
goto abort;
if (!(inputDevPort = CreatePort ("NewPopInputPort", 0)))
goto abort;
if (!(inputRequestBlock = (void *) CreateExtIO (inputDevPort, sizeof (struct IOStdReq))))
goto abort;
if (!(timerport = CreatePort ("NewPopTimerPort", 0)))
goto abort;
if (!(timerreq = (struct timerequest *) CreateExtIO (timerport, sizeof (struct timerequest))))
goto abort;
if ((creatsignum = AllocSignal (-1)) == -1)
goto abort;
if ((blanksignum = AllocSignal (-1)) == -1)
goto abort;
if ((mousemovenum = AllocSignal (-1)) == -1)
goto abort;
if (!(GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0)))
goto abort;
if (!(LayersBase = (struct LayersBase *) OpenLibrary ("layers.library", 0)))
goto abort;
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0)))
goto abort;
if (!(DiskfontBase = OpenLibrary ("diskfont.library", 0)))
goto abort;
if (!(ExecBase = (struct ExecBase *) OpenLibrary ("exec.library", 0)))
goto abort;
if (LOCK)
ReqBase = OpenLibrary ("req.library", 0);
if (!NEWPOPLITE)
{
if (MEMORYMONWIDTH)
{
struct MemHeader *mem;
Forbid ();
for (mem = (struct MemHeader *)ExecBase->MemList.lh_Head;
mem->mh_Node.ln_Succ;
mem = (struct MemHeader *)mem->mh_Node.ln_Succ)
{
if (mem -> mh_Attributes & MEMF_CHIP)
maxchip += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
/* Just in case we have something that is both chip and fast... */
if (mem -> mh_Attributes & MEMF_FAST)
maxfast += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
}
Permit ();
}
else
GAPBETWEEN3 = 0;
if (SCSIIOMONWIDTH)
{
Forbid ();
if (scsifriend = FindTask (SCSITASKNAME))
if (!(scsifriend->tc_Flags & TF_SWITCH))
{
scsifriend->tc_Switch = scsifriendlosing;
scsifriend->tc_Flags |= TF_SWITCH;
scsifriendinstalled = 1;
}
Permit ();
}
else
GAPBETWEEN2 = 0;
if (!CPULOADMONWIDTH)
GAPBETWEEN = 0;
WindowWidth = MEMORYMONWIDTH + GAPBETWEEN3 + SCSIIOMONWIDTH +
GAPBETWEEN2 + CPULOADMONWIDTH + GAPBETWEEN + MAXTEXTWIDTH;
WindowHeight = WINDOWHEIGHT;
NewWindow.LeftEdge = GfxBase->NormalDisplayColumns - WindowWidth - STARTXOFFSET;
NewWindow.TopEdge = 1;
NewWindow.Width = WindowWidth;
NewWindow.Height = WindowHeight;
if (WEWANTWINDOWDRAG)
{
WDragGadget.Height = WindowHeight;
WDragGadget.Width = WindowWidth;
}
else
NewWindow.FirstGadget = NULL;
if (BACKDROPWINDOW)
NewWindow.Flags |= BACKDROP;
if ((NewWindow.LeftEdge < 0) || !(titlewindow = OpenWindow (&NewWindow)))
goto abort;
titleRP = titlewindow->RPort;
SetAPen (titleRP, 1);
SetBPen (titleRP, 1);
SetDrMd (titleRP, JAM2);
RectFill (titleRP, 0, 0, (WindowWidth - 1), (WindowHeight - 1));
if (MAXTEXTWIDTH)
{
struct TextAttr textAttr = {NULL, 0, 0, 0};
textAttr.ta_Name = FONTNAME;
textAttr.ta_YSize = FONTSIZE;
if (textFont = OpenFont (&textAttr))
{
if ((textFont->tf_YSize != FONTSIZE) || (textFont->tf_Style != 0))
{
CloseFont (textFont);
if (!(textFont = OpenDiskFont (&textAttr)))
goto abort;
}
}
else
{
if (!(textFont = OpenDiskFont (&textAttr)))
goto abort;
}
SetFont (titleRP, textFont);
}
LIdle = ExecBase->IdleCount;
LDisp = ExecBase->DispCount;
}
if (OpenDevice ("input.device", 0, (struct IORequest *) inputRequestBlock, 0))
goto abort;
handlerStuff.is_Data = (APTR) NULL;
handlerStuff.is_Code = (VOID (*) ()) myhandler;
handlerStuff.is_Node.ln_Pri = 51;
timersig = (1 << timerport->mp_SigBit);
creatclisig = 1 << creatsignum;
unblanksig = 1 << blanksignum;
mousemovesig = 1 << mousemovenum;
inputRequestBlock->io_Command = IND_ADDHANDLER;
inputRequestBlock->io_Data = (APTR) & handlerStuff;
DoIO ((struct IORequest *) inputRequestBlock);
if (OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) timerreq, 0))
goto abort;
QueueTimer (timerreq, 1 /* 1/60th of a second */ );
}
{
UWORD newsecond;
ULONG sig, Seconds, Micros, LastSeconds = 0;
int topscreenwidth = GfxBase->NormalDisplayColumns;
int topscreenheight = GfxBase->NormalDisplayRows;
for (;;)
{
sig = Wait (creatclisig | unblanksig | timersig |
mousemovesig | SIGBREAKF_CTRL_C);
if (sig & mousemovesig)
{
int left, right, upper, lower;
if (!blankscreen)
{
int lock = LockIBase (0);
struct Screen *screen = IntuitionBase->FirstScreen;
while (screen && IntuitionBase->MouseY <
(screen->TopEdge << ((screen->ViewPort.Modes & LACE) ? 0 : 1)))
screen = screen->NextScreen;
if (screen)
{
topscreenwidth = screen->Width << ((screen->ViewPort.Modes & HIRES) ? 0 : 1);
topscreenheight = screen->Height >> ((screen->ViewPort.Modes & LACE) ? 1 : 0);
}
else
{
topscreenwidth = GfxBase->NormalDisplayColumns;
topscreenheight = GfxBase->NormalDisplayRows;
}
UnlockIBase (lock);
}
left = IntuitionBase->MouseX < 10;
right = (topscreenwidth - IntuitionBase->MouseX) < 10;
upper = IntuitionBase->MouseY < 10;
lower = (topscreenheight - IntuitionBase->MouseY / 2) < 10;
instantblank = ((((ULC == 1) && upper) || ((LLC == 1) && lower)) && left) ||
((((URC == 1) && upper) || ((LRC == 1) && lower)) && right);
defeatblank = ((((ULC == 2) && upper) || ((LLC == 2) && lower)) && left) ||
((((URC == 2) && upper) || ((LRC == 2) && lower)) && right);
}
CurrentTime (&Seconds, &Micros);
newsecond = (Seconds != LastSeconds);
LastSeconds = Seconds;
if (newsecond && !NEWPOPLITE && !blankscreen)
{
SHORT x = 0;
ULONG DIdle, DDisp, Usage;
long t;
struct tm *p;
char *timestr;
UpfrontLayer (0L, titlewindow->WLayer);
DIdle = ExecBase->IdleCount - LIdle;
DDisp = ExecBase->DispCount - LDisp;
LIdle = ExecBase->IdleCount;
LDisp = ExecBase->DispCount;
if (!DDisp)
DDisp++;
if (MEMORYMONWIDTH)
{
int pixels;
SetAPen (titleRP, 3);
pixels = AvailMem (MEMF_CHIP) * MEMORYMONWIDTH / maxchip;
RectFill (titleRP, x, 0, x+pixels, ((WindowHeight/2) - 1));
SetAPen (titleRP, 1);
RectFill (titleRP, x+pixels+1, 0, MEMORYMONWIDTH, ((WindowHeight/2) - 1));
SetAPen (titleRP, 2);
pixels = AvailMem (MEMF_FAST) * MEMORYMONWIDTH / maxfast;
RectFill (titleRP, x, (WindowHeight/2), x+pixels, (WindowHeight - 1));
SetAPen (titleRP, 1);
RectFill (titleRP, x+pixels+1, (WindowHeight/2), MEMORYMONWIDTH, (WindowHeight - 1));
x = MEMORYMONWIDTH;
}
x += GAPBETWEEN3;
if (scsifriendinstalled)
{
Usage = (scsiDisp * 256) / (DDisp + DIdle);
if (Usage > MAXSCSIUSAGE)
Usage = MAXSCSIUSAGE;
SetAPen (titleRP, 3);
ScrollRaster (titleRP, 1, 0, x, 0, x + SCSIIOMONWIDTH, (WindowHeight - 1));
x += SCSIIOMONWIDTH;
Move (titleRP, x, (WindowHeight - 1));
Draw (titleRP, x, WindowHeight - ((WindowHeight * Usage) / MAXSCSIUSAGE));
scsiDisp = 0;
}
else
x += SCSIIOMONWIDTH;
x += GAPBETWEEN2;
if (CPULOADMONWIDTH)
{
/* There be magic below! Where does 456 come from? :-) */
if (scsiDisp < DDisp)
Usage = ((DDisp - scsiDisp) * 456) / (DDisp + DIdle);
else
Usage = 0;
if (Usage < 200)
Usage = 0;
else
Usage = Usage - 200;
ScrollRaster (titleRP, 1, 0, x, 0, x + CPULOADMONWIDTH, (WindowHeight - 1));
x += CPULOADMONWIDTH;
SetAPen (titleRP, 2);
Move (titleRP, x, (WindowHeight - 1));
Draw (titleRP, x, WindowHeight - ((WindowHeight * Usage) / 256));
}
x += GAPBETWEEN;
if (MAXTEXTWIDTH)
{
time (&t);
p = localtime (&t);
timestr = asctime (p);
if (WIMPYCLOCK)
switch ((timestr[11] - '0') * 10 + (timestr[12] - '0'))
{
case 0: timestr[11] = '1'; timestr[12] = '2'; goto am;
case 12: goto pm;
case 13: timestr[11] = '0'; timestr[12] = '1'; goto pm;
case 14: timestr[11] = '0'; timestr[12] = '2'; goto pm;
case 15: timestr[11] = '0'; timestr[12] = '3'; goto pm;
case 16: timestr[11] = '0'; timestr[12] = '4'; goto pm;
case 17: timestr[11] = '0'; timestr[12] = '5'; goto pm;
case 18: timestr[11] = '0'; timestr[12] = '6'; goto pm;
case 19: timestr[11] = '0'; timestr[12] = '7'; goto pm;
case 20: timestr[11] = '0'; timestr[12] = '8'; goto pm;
case 21: timestr[11] = '0'; timestr[12] = '9'; goto pm;
case 22: timestr[11] = '1'; timestr[12] = '0'; goto pm;
case 23: timestr[11] = '1'; timestr[12] = '1'; goto pm;
default: am: timestr[19] = 'a'; break;
pm: timestr[19] = 'p'; break;
}
Move (titleRP, x, STARTYOFFSET);
Text (titleRP, timestr, 24);
x += TextLength (titleRP, timestr, 24);
SetAPen (titleRP, 1);
if (x < (WindowWidth - 1))
RectFill (titleRP, x, 0, (WindowWidth - 1), (WindowHeight - 1));
}
}
if (blankscreen)
{
if (NICENEWPOP)
{
if (newsecond)
{
/*changecolor ();*/
SetTaskPri (child, 10);
}
}
else
{
/*if (newsecond)*/
changecolor ();
updatedisplay ();
}
}
if (sig & SIGBREAKF_CTRL_C)
goto abort;
if (sig & creatclisig)
{
if (!(blankscreen && LOCK))
{
WBenchToFront ();
if (DOSBase->dl_lib.lib_Version < 36)
Execute(COMMAND, nullfh, nullfh);
else
{
static struct TagItem stags[4] =
{
{SYS_Input, NULL},
{SYS_Output, NULL},
{SYS_UserShell, TRUE},
{TAG_DONE, 0}
};
stags[0].ti_Data = nullfh;
System(COMMAND, stags);
}
if (blankscreen)
goto unblank;
}
}
{
static WORD joy0, oldjoy0, joy1, oldjoy1;
joy0 = *((WORD *)0x00dff00a) & 0x0303;
joy1 = *((WORD *)0x00dff00c) & 0x0303;
if ((joy0 != oldjoy0) || (joy1 != oldjoy1))
{
oldjoy0 = joy0;
oldjoy1 = joy1;
if (blankscreen && !instantblank)
goto unblank;
}
}
if ((sig & unblanksig) && blankscreen && !instantblank)
{
unblank:
if (LOCK && ReqBase)
{
char InputPassWord[MAXPASSWORD];
static int trywait;
SetRGB4 (blankVP, 17, 4, 4, 4);
SetRGB4 (blankVP, 18, 8, 8, 8);
SetRGB4 (blankVP, 19, 12, 12, 12);
createsecurer ();
InputPassWord[0] = 0;
if ((trywait++ % 2) /*&&
GetString (InputPassWord, "Type password, then hit return.",
blankwindow, MAXPASSWORD + 10, MAXPASSWORD)*/)
{
killsecurer ();
UpfrontLayer (0L, blankwindow->WLayer);
if (strcmp (InputPassWord, PASSWORD))
goto noway;
}
else
{
killsecurer ();
UpfrontLayer (0L, blankwindow->WLayer);
goto noway;
}
}
if (NICENEWPOP)
killchild ();
CloseWindow (blankwindow);
CloseScreen (blankscreen);
blankscreen = NULL;
noevents = 0;
noway: ;
}
if (sig & timersig)
{
GetMsg (timerport);
if (blankscreen && NICENEWPOP)
QueueTimer (timerreq, 60 /* One second */ );
else
QueueTimer (timerreq, 1 /* 1/60th of a second*/ );
if ((instantblank || (noevents++ >= (TIMEOUT * 60))) && !blankscreen && !defeatblank && TIMEOUT)
{
NewScreen.Height = GfxBase->NormalDisplayRows * 2;
NewScreen.Width = GfxBase->NormalDisplayColumns;
if (blankscreen = OpenScreen (&NewScreen))
{
ylim = blankscreen->Height - 1;
xlim = blankscreen->Width - 1;
NewBlankerWindow.Screen = blankscreen;
NewBlankerWindow.Height = blankscreen->Height;
NewBlankerWindow.Width = blankscreen->Width;
if (blankwindow = OpenWindow (&NewBlankerWindow))
{
static UWORD __chip NULLpointer[1] = {0x0000};
blankRP = blankwindow->RPort;
blankVP = &(blankscreen->ViewPort);
SetPointer (blankwindow, NULLpointer, 0, 0, 0, 0);
changecolor ();
SetRGB4 (blankVP, 0, 0, 0, 0);
SetRGB4 (blankVP, 17, 0, 0, 0);
SetRGB4 (blankVP, 18, 0, 0, 0);
SetRGB4 (blankVP, 19, 0, 0, 0);
SetDrMd (blankRP, JAM1);
UpfrontLayer (0L, blankwindow->WLayer);
if (NICENEWPOP)
createchild ();
}
else
{
CloseScreen (blankscreen);
blankscreen = NULL;
}
}
}
}
if (blankscreen)
ScreenToFront (blankscreen);
}
}
abort:
#define SafeClose(fh) if (fh) Close (fh)
#define SafeDeletePort(port) if (port) DeletePort (port)
#define SafeCloseLibrary(lib) if (lib) CloseLibrary ((struct Library *) lib)
#define SafeFreeSignal(signum) if (signum != -1) FreeSignal (signum)
#define SafeCloseFont(font) if (font) CloseFont (font)
#define SafeCloseWindow(window) if (window) CloseWindow (window)
SetTaskPri (buddy, oldPriority);
SafeDeletePort (port);
if (scsifriendinstalled)
{
Forbid ();
if (scsifriend = FindTask (SCSITASKNAME))
if (scsifriend->tc_Switch == scsifriendlosing)
{
UBYTE oldpri = SetTaskPri (scsifriend, 21);
Permit ();
/* Make SURE scsifriend has lost the CPU!
// I don't know why this fixed a problem
// people were having with A3000's/2.0/C=
// controllers, but it seems to work! */
Forbid ();
SetTaskPri (scsifriend, oldpri);
scsifriend->tc_Flags &= ~TF_SWITCH;
scsifriend->tc_Switch = NULL;
}
Permit ();
}
SafeCloseWindow (titlewindow);
if (timerreq)
{
if (timerreq->tr_node.io_Device)
{
if (!CheckIO ((struct IOStdReq *) timerreq));
{
AbortIO ((struct IOStdReq *) timerreq);
WaitIO ((struct IOStdReq *) timerreq);
}
CloseDevice ((struct IORequest *) timerreq);
}
DeleteExtIO ((struct IOStdReq *) timerreq);
}
if (inputRequestBlock)
{
if (inputRequestBlock->io_Device)
{
inputRequestBlock->io_Command = IND_REMHANDLER;
inputRequestBlock->io_Data = (APTR) & handlerStuff;
DoIO ((struct IORequest *) inputRequestBlock);
CloseDevice ((struct IORequest *) inputRequestBlock);
}
DeleteExtIO (inputRequestBlock);
}
SafeCloseFont (textFont);
SafeDeletePort (timerport);
SafeFreeSignal (creatsignum);
SafeFreeSignal (blanksignum);
SafeFreeSignal (mousemovenum);
if (blankscreen)
{
if (NICENEWPOP)
killchild ();
CloseWindow (blankwindow);
CloseScreen (blankscreen);
}
SafeCloseLibrary (IntuitionBase);
SafeCloseLibrary (GfxBase);
SafeCloseLibrary (LayersBase);
SafeCloseLibrary (DiskfontBase);
SafeCloseLibrary (ExecBase);
SafeCloseLibrary (ReqBase);
SafeDeletePort (inputDevPort);
SafeClose (nullfh);
grandexit: ;
return (0);
}
void
changecolor (void)
{
static struct color currentcolor = {127, 0, 254};
static struct color colordelta = {-1, 1, 1};
static unsigned long table[] = { (1<<16) + 1, 0, 0, 0, 0 };
switch (rand () % 3)
{
case 0:
currentcolor.red += colordelta.red;
if (currentcolor.red == 0 ||
currentcolor.red == 255)
colordelta.red = -colordelta.red;
break;
case 1:
currentcolor.green += colordelta.green;
if (currentcolor.green == 0 ||
currentcolor.green == 255)
colordelta.green = -colordelta.green;
break;
case 2:
currentcolor.blue += colordelta.blue;
if (currentcolor.blue == 0 ||
currentcolor.blue == 255)
colordelta.blue = -colordelta.blue;
break;
}
table[1] = ((unsigned long) currentcolor.red) << 24;
table[2] = ((unsigned long) currentcolor.green) << 24;
table[3] = ((unsigned long) currentcolor.blue) << 24;
LoadRGB32 (blankVP, table);
}
void
updatedisplay (void)
{
static SHORT x[2], y[2], xd[2], yd[2], ox[2][16], oy[2][16];
static j;
SHORT i, k;
if (j == 0)
{
x[0] = rand () % xlim + 1;
if ((x[1] = x[0] + rand () % (xlim / 6) - (xlim / 12)) > xlim)
x[1] = xlim;
if (x[1] < 0)
x[1] = 0;
y[0] = rand () % ylim + 1;
if ((y[1] = y[0] + rand () % (ylim / 4) - (ylim / 8)) > ylim)
y[1] = ylim;
if (y[1] < 0)
y[1] = 0;
xd[0] = 11;
yd[0] = 7;
xd[1] = 3;
yd[1] = 4;
}
SetAPen (blankRP, 0);
Move (blankRP, ox[0][j & 15], oy[0][j & 15]);
Draw (blankRP, ox[1][j & 15], oy[1][j & 15]);
SetAPen (blankRP, 1);
Move (blankRP, x[0], y[0]);
Draw (blankRP, x[1], y[1]);
for (i = 0; i < 2; i++)
{
ox[i][j & 15] = x[i];
oy[i][j & 15] = y[i];
x[i] += xd[i];
y[i] += yd[i];
if (abs (x[1] - x[0]) > xlim / 4)
{
x[i] -= xd[i] * 4 / 3;
xd[i] = -xd[i] / 2;
}
if (abs (y[1] - y[0]) > ylim / 3)
{
y[i] -= yd[i] * 4 / 3;
yd[i] = -yd[i] / 2;
}
if (x[i] < 0)
{
x[i] = 0;
xd[i] = -xd[i];
}
else if (x[i] > xlim)
{
x[i] = xlim;
xd[i] = -xd[i];
}
if (y[i] < 0)
{
y[i] = 0;
yd[i] = -yd[i];
}
else if (y[i] > ylim)
{
y[i] = ylim;
yd[i] = -yd[i];
}
if (((rand () >> 5) & 127) < 2)
{
if (xd[i] < 1)
k = 1;
xd[i] = (rand () >> 5) & 7;
if (k == (1 - i))
xd[i] = -xd[i];
k = 0;
}
if (((rand () >> 5) & 255) < 50)
{
if (yd[i] < 1)
k = 1;
yd[i] = (rand () >> 5) & 7;
if (k == (1 - i))
yd[i] = -yd[i];
k = 0;
}
}
++j;
}
void
QueueTimer (struct timerequest * tr, ULONG ticks)
{
tr->tr_node.io_Command = TR_ADDREQUEST;
tr->tr_time.tv_secs = ticks / 60;
tr->tr_time.tv_micro = (ticks % 60) * 1000000 / 60;
SendIO ((struct IORequest *) tr);
}